package com.sfac.config;

import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

/**
 * @Description DataSourceProxyConfig
 * @Author JiangHu
 * @Date 2022/7/20 10:32
 */
@Configuration
@EnableTransactionManagement
@MapperScan(
		sqlSessionFactoryRef = "sqlSessionFactory",
		sqlSessionTemplateRef="sqlSessionTemplate",
		basePackages = "com.sfac.dao")
public class DataSourceProxyConfig {

	// hikari config
	@Value("${spring.datasource.hikari.maximum-pool-size}")
	private int maximumPoolSize;
	@Value("${spring.datasource.hikari.minimum-idle}")
	private int minimumIdle;
	@Value("${spring.datasource.hikari.idle-timeout}")
	private long idleTimeout;
	@Value("${spring.datasource.hikari.auto-commit}")
	private boolean autoCommit;

	// mybatis config
	@Value("${mybatis.configuration.map-underscore-to-camel-case}")
	private boolean mapUnderscoreToCamelCase;

	@Bean(name="hikariDataSource")
	@ConfigurationProperties(prefix = "spring.datasource")
	public HikariDataSource dataSource() {
		HikariDataSource hikariDataSource = new HikariDataSource();
		hikariDataSource.setMaximumPoolSize(maximumPoolSize);
		hikariDataSource.setMinimumIdle(minimumIdle);
		hikariDataSource.setIdleTimeout(idleTimeout);
		hikariDataSource.setAutoCommit(autoCommit);
		return hikariDataSource;
	}

	@Bean(name="dataSourceProxy")
	public DataSource dataSourceProxy(@Qualifier("hikariDataSource") DataSource dataSource) {
		return new DataSourceProxy(dataSource);
	}

	@Bean(name="sqlSessionFactory")
	public SqlSessionFactory sqlSessionFactoryBean(
			@Qualifier("dataSourceProxy") DataSource dataSourceProxy) throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSourceProxy);
		org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
		configuration.setMapUnderscoreToCamelCase(mapUnderscoreToCamelCase);
		bean.setConfiguration(configuration);
		return bean.getObject();
	}

	@Bean(name="sqlSessionTemplate")
	public SqlSessionTemplate mainDbSqlSessionTemplate(
			@Qualifier("sqlSessionFactory") SqlSessionFactory sessionfactory) {
		return new SqlSessionTemplate(sessionfactory);
	}

	@Bean(name = "mybatisTransactionManager")
	public PlatformTransactionManager transactionManager(
			@Qualifier("dataSourceProxy") DataSource dataSourceProxy) {
		return new DataSourceTransactionManager(dataSourceProxy);
	}
}
